package com.adee.netty.demo;

import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;

import java.util.concurrent.TimeUnit;

/*
* 说明
* 继承一个HandlerAdapter: ChannelInboundHandlerAdapter
* */
public class NettyServerHandler extends ChannelInboundHandlerAdapter {
    /*
    * 读取实际数据
    * 1.ChannelHandlerContext ctx: 上下文对象，含有管道pipeLine、通道Channel，地址
    * 2.Object msg: 就是客户端发送的数据，默认Object
    * */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        // 一个handler只跑在一个线程中，通过execute方法向taskQueue中添加的异步任务会同步按顺序执行
        // 比如这里有一个耗时的业务 -> 异步执行 -> 提交该channel对应的NIOEventLoop的taskQueue中
        // 缺点：下面两种方式添加的任务，仍然在当前一个线程中执行，并不是异步执行的，仍会同步执行
        // 解决方案1 用户程序自定义的普通任务，可添加多个任务，这些任务在该线程中依次执行
        ctx.channel().eventLoop().execute(() -> {
            try {
                Thread.sleep(10 * 1000);
                ctx.writeAndFlush(Unpooled.copiedBuffer("hello, 客户端 喵2~", CharsetUtil.UTF_8));
                System.out.println("go on ...");
            } catch(Exception e) {
                System.out.println("发生异常：" + e.getMessage());
            }
        });
        ctx.channel().eventLoop().execute(() -> {
            try {
                Thread.sleep(10 * 1000);
                ctx.writeAndFlush(Unpooled.copiedBuffer("hello, 客户端 喵3~", CharsetUtil.UTF_8));
                System.out.println("go on ...");
            } catch(Exception e) {
                System.out.println("发生异常：" + e.getMessage());
            }
        });

        // 解决方案2 用户自定义定时任务，该任务是提交到scheduledTaskQueue任务队列中
        ctx.channel().eventLoop().schedule(() -> {
            try {
                Thread.sleep(5 * 1000);
                ctx.writeAndFlush(Unpooled.copiedBuffer("hello, 客户端 喵4~", CharsetUtil.UTF_8));
                System.out.println("go on ...");
            } catch(Exception e) {
                System.out.println("发生异常：" + e.getMessage());
            }
        }, 5, TimeUnit.SECONDS);




//        System.out.println(">>>>>>>>>>>>>>>>>服务器读取线程 " + Thread.currentThread().getName());
//        System.out.println("server ctx=" + ctx);
//        // ByteBuf是Netty提供的，不是nio的
//        ByteBuf buf = (ByteBuf) msg;
//        System.out.println("客户端发送的消息是：" + buf.toString(CharsetUtil.UTF_8));
//        System.out.println("客户端地址：" + ctx.channel().remoteAddress());
    }
    /* 数据读取完毕 */
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        // writeAndFlush是write + flush
        // 将数据写入到缓存并刷新
        // 一般讲，我们对发送的这个数据进行编码
        ctx.writeAndFlush(Unpooled.copiedBuffer("hello，客户端~", CharsetUtil.UTF_8));
    }
    /* 处理异常，一般是关闭通道 */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.close();
    }

}
